const canvas = document.createElement('canvas') ;
document.body.append(canvas) ;
canvas.width = window.innerWidth ;
canvas.height = window.innerHeight ;
const ctx = canvas.getContext('2d') ;

ctx.translate(0,canvas.height);
ctx.scale(1,-1);

class Fireworks{
    constructor(x , y){
        this.x = x ;
        this.y = y ;
        this.r = 6 ;
        this.opacity = 1 ;
        this.count = 400 ;
        this.particles = [] ;
    }
    draw(){
        //绘制多个小球，形成主体形状
        this.opacity = this.opacity<0.2?0.2:this.opacity ;
        for(let i=0;i<100;i++){
            const ball = new Ball(this.x , this.y-i , this.r-i/20 , `rgba(200,200,50,${this.opacity-i/100})` );
            ball.draw();
        }
    }
    bomb(){
        //绘制爆炸的粒子
        if(this.particles.length == 0){
            //首次爆炸
            const hd = Math.PI * 2 / this.count ;
            //const color = `rgba(${Math.random()*256},${Math.random()*256},${Math.random()*256},0.8)` ;
            const color = `hsl(${Math.random()*360},50%,50%)`;
            for(let i=0;i<this.count;i++){
                const dirx = Math.cos(hd * i) * Math.random() * 4 ;
                const diry = Math.sin(hd * i) * Math.random() * 4 ;
                const particle = new Particle(this.x,this.y,dirx ,diry,color,i%2==0) ;
                this.particles.push(particle);
                particle.draw();
            }
        }else{
            //已经爆炸，产生了粒子，重绘粒子即可
            this.particles.forEach((particle,i)=>{
                particle.update();
            })
        }
    }
}

class Ball{
    constructor(x,y,r,color){
        this.x = x ;
        this.y = y ;
        this.r = r ;
        this.color = color ;
    }
    draw(){
        ctx.save();
        ctx.beginPath();
        ctx.fillStyle = this.color ;
        ctx.arc(this.x,this.y,this.r,0,Math.PI*2);
        ctx.fill();
        ctx.restore();
    }
}

class Particle{
    constructor(x , y , dirx , diry , color,type){
        this.x = x ;
        this.y = y ;
        this.r = 3 ;
        this.dirx = dirx ;
        this.diry = diry ;
        this.color = color ;
        this.type = type ;
    }
    draw(){
        if(this.type){
            ctx.save();
            ctx.beginPath();
            ctx.fillStyle = this.color ;
            ctx.arc(this.x,this.y,this.r,0,Math.PI*2) ;
            ctx.fill();
            ctx.restore();
        }
        this.type = !this.type ;
    }
    
    update(){
        this.x += this.dirx ;
        this.y += this.diry ;
        this.dirx *= 0.99 ;
        this.diry *= 0.98 ;
        this.draw();
    }
}



const fireworksArray = [] ;
const bombArray = [] ;
let sum = 0 ;
function move(){
    ctx.clearRect(0,0,canvas.width,canvas.height);
    
    if(sum%50 == 0){
        //到达时间，释放一个新的烟花
        const x = Math.random() * canvas.width * 3 / 4 + canvas.width / 8 ;
        const y = Math.random() * 100 ;
        const fire = new Fireworks(x,y);
        fireworksArray.push(fire);
    }

    if(fireworksArray.length == 4){
        //最开始的那个烟花，就可以爆炸了
        const fire = fireworksArray.shift();
        bombArray.push(fire);
    }

    if(bombArray.length == 4){
        //最开始爆炸的烟花结束
        bombArray.shift();
    }

    //重绘所有烟花(主体)
    fireworksArray.forEach((fire,i)=>{
        fire.draw();
        fire.y +=4;
        fire.opacity -= 0.01
    });

    //重置所有烟花（爆炸）
    bombArray.forEach((fire,i)=>{
        fire.bomb();
    })

    sum ++ ;
    requestAnimationFrame(move)
}  
move();